"""
首先要有一个实现了__get__()、__set__()和__delete__()中的其中任意一种方法的新式类，

如果一个类有个属性是上述的类的实例化对象，那么这个属性（也就是那个实例化对象)，就是一个描述符。
"""


# 方式1: 描述符放到类属性的位置
# class MyDescriptor:
#     def __init__(self):
#         print("--MyDescriptor init方法--")
#
#     def __get__(self, instance, owner):
#         print('get called')
#         return 'get'
#
#     def __set__(self, instance, value):
#         print('set called')
#
#     def __delete__(self, instance):
#         print('delete called')
#
#
# class Foo:
#     attr = MyDescriptor()  # 这里就是描述符
#
#
# f = Foo()
# f.attr = 100  # 会自动调用__set__方法
# print(f.attr)  # 会自动调用__get__方法


# 方式2：用装饰器的方式
class MyDescriptor:
    def __init__(self, func):
        print("--MyDescriptor init方法--")
        self.__func = func

    def __get__(self, instance, owner):
        print('get called')
        return self.__func(instance)
        # return 'get'

    def __set__(self, instance, value):
        print('set called')

    def __delete__(self, instance):
        print('delete called')


class Foo:

    @MyDescriptor  # 等价于 print_test = MyDescriptor(print_test)
    def print_test(self):
        print("hahah，我是print_test方法")
        return 100


f = Foo()
print(f.print_test)
"""
1. print_test已经被 MyDescriptor修饰了，且MyDescriptor拥有__get__/__set__/__delete__
所以说，print_test已经变成了描述符
2. 对象.描述符 就会自动调用 __get__
3. 只要在__get__方法中，调用之前print_test指向的原方法即可
"""
